home *** CD-ROM | disk | FTP | other *** search
/ Chip 2007 January, February, March & April / Chip-Cover-CD-2007-02.iso / Pakiet bezpieczenstwa / mini Pentoo LiveCD 2006.1 / mpentoo-2006.1.iso / modules / nessus-2.2.8.mo / usr / lib / nessus / plugins / http_func.inc < prev    next >
Text File  |  2005-03-31  |  11KB  |  475 lines

  1. # -*- Fundamental -*-
  2. #
  3. # (C) 2002 Michel Arboi <arboi@alussinan.org>
  4. # get_http_port (C) Georges Dagousset
  5. # $Revision: 1.74 $
  6.  
  7.  
  8. #
  9. # That's for chunk-decoding
  10. #
  11. function __hex_value(num)
  12. {
  13.    if(num == "a")return(10);
  14.    if(num == "b")return(11);
  15.    if(num == "c")return(12);
  16.    if(num == "d")return(13);
  17.    if(num == "e")return(14);
  18.    if(num == "f")return(15);
  19.    return(int(num));
  20. }
  21.  
  22.  
  23. function hex2dec(xvalue)
  24. {
  25.  local_var ret, l, i, n, m;
  26.   
  27.  if(!xvalue)return(0);
  28.  xvalue = tolower(xvalue);
  29.  if ( '\r\n' >< xvalue )
  30.      l = strlen(xvalue) - 2;
  31.  else if ( '\n' >< xvalue)
  32.     l = strlen(xvalue) - 1;
  33.  else   l = strlen(xvalue);
  34.  
  35.  
  36.  ret = 0;
  37.  m = 1;
  38.  if ( l == 0 ) return 0;
  39.  
  40.  # Remove the trailing spaces
  41.  while(xvalue[l - 1]==" " && l > 0)l--;
  42.  
  43.  for(i=l;i>0;i--)
  44.  {
  45.   n = __hex_value(num:xvalue[i - 1]) * m;
  46.   ret = ret + n;
  47.   m = m * 16;
  48.  }
  49.  return int(ret);
  50. }
  51.  
  52. #---------------------------------------------------#
  53.  
  54. function get_http_banner(port)
  55. {
  56.   local_var soc, sb, banner, req, body;
  57.   
  58.   if ( get_kb_item("Services/www/" + port + "/broken") ) return NULL;
  59.   
  60.   if (! get_port_state(port)) return (0);
  61.   sb = strcat("www/real_banner/", port);
  62.   banner = get_kb_item(sb);
  63.   if(banner) return(banner);
  64.   
  65.   sb = strcat("www/banner/", port);
  66.   banner = get_kb_item(sb);
  67.   if (banner) return(banner);
  68.  
  69.   soc = http_open_socket(port);
  70.   if(!soc) return (NULL);
  71.   req = http_get(item:"/", port:port);
  72.   send(socket:soc, data:req);
  73.   banner = http_recv_headers(soc);
  74.   #body = http_recv_body(socket:soc, headers: banner);
  75.   http_close_socket(soc);
  76.   if(banner)
  77.   {
  78.    if ( defined_func("replace_kb_item") )
  79.       replace_kb_item(name: sb, value: banner);
  80.    else
  81.       set_kb_item(name: sb, value: banner);
  82.   }
  83.   return(banner);
  84. }
  85.  
  86. # Submitted by Georges Dagousset
  87. # Usage: port = get_http_port(default:80);
  88. function get_http_port(default)
  89. {
  90.   local_var    soc, port, p, r, then, now;
  91.  
  92.   if ( defined_func("unixtime") )
  93.     then = unixtime();
  94.  
  95.   port = get_kb_item("Services/www");
  96.   if ( port ) return port;
  97.  
  98.   p = get_kb_item("Services/www/" + default + "/broken");
  99.   if ( p ) exit(0);
  100.  
  101.   p = get_kb_item("Services/www/" + default + "/working");
  102.   if ( p ) return default;
  103.  
  104.   soc = http_open_socket(default);
  105.   if ( ! soc ) 
  106.   {
  107.    set_kb_item(name:"Services/www/" + default + "/broken", value:1);
  108.    exit(0);
  109.   }
  110.  
  111.   send(socket:soc, data:'GET / HTTP/1.1\r\nHost: ' + get_host_name() + '\r\n\r\n');
  112.   r = recv_line(socket:soc, length:4096);
  113.   close(soc);
  114.   if ( defined_func("unixtime") )
  115.     now = unixtime();
  116.   if ( ! r || "HTTP" >!< r || ( ereg(pattern:"^HTTP.* 403 ", string:r) && (now - then >= 5)  ) )
  117.   {
  118.    set_kb_item(name:"Services/www/" + default + "/broken", value:1);
  119.    exit(0);
  120.   }
  121.  
  122.   
  123.   set_kb_item(name:"Services/www/" + default + "/working", value:1);
  124.   return default;
  125. }
  126.  
  127. # (C) Georges Dagousset
  128. # Usage:
  129. # banner = get_http_banner(port:port);
  130. # if (php_ver_match(banner:banner, 
  131. #     pattern:".*PHP/((3.*)|(4\.0.*)|(4\.1\.[01].*))"))
  132. #       security_hole(port);
  133. #
  134. function php_ver_match(banner, pattern) 
  135. {
  136.   local_var    line;
  137.   line = egrep(pattern:"^Server:.*", string:banner);
  138.   if(ereg(pattern:pattern, string:line))return(1);
  139.   else
  140.   {
  141.     line = egrep(pattern:"^X-Powered-By:.*", string:banner);
  142.     if(ereg(pattern:pattern, string:line))return(1);
  143.   }
  144.   return(0);
  145. }
  146.  
  147. function http_is_dead(port, retry)
  148. {
  149.   local_var    soc, url, req, code, h, h2, b;
  150.   
  151.   if(!retry)retry = 2;
  152.  
  153.   soc = http_open_socket(port);
  154.   while (!soc && i++ < retry)
  155.   {
  156.     sleep(1);
  157.     soc = http_open_socket(port);
  158.   }
  159.   if (! soc) return (1);
  160.   # NB: http_head does not work against SWAT & VNC (& probably others...)
  161.   url = strcat("/NessusTest", rand(), ".html");
  162.   req = http_get(item: url, port:port);
  163.   
  164.   send(socket:soc, data:req);
  165.   code = recv_line(socket:soc, length: 1024);
  166.   if (code)
  167.   {
  168.     h = http_recv_headers(soc);
  169.     h2 = strcat(code, h);
  170.     b = http_recv_body(socket: soc, headers: h2);
  171.   }
  172.   http_close_socket(soc);
  173.   if (! code) return (1);
  174.   # 500: internal server error; 502: Bad gateway; 503: service unavailable
  175.   # 504: gateway timeout
  176.   if (ereg(pattern: "^50[234]", string: code)) return(1);
  177.   return (0);
  178. }
  179.  
  180. # This function was originaly written by SecurITeam in 
  181. # badblue_directory_traversal.nasl
  182. # I (=MA) enhanced it.
  183. # NB: it works with AUTOEXEC.BAT, WIN.INI and BOOT.INI
  184. # quickcheck should be set to 0 if the server does not return clean 404 code,
  185. # i.e., if "www/no404/"+port is defined in the KB
  186.  
  187. function do_check_win_dir_trav(port, url, quickcheck)
  188. {
  189.   local_var    soc, req, cod, buf;
  190.   #display("check_win_dir_trav(port=", port, ", url=", url, ", quickcheck=", quickcheck, ")\n");
  191.   soc = http_open_socket(port);
  192.   if(! soc)
  193.   {
  194.    # display("check_win_dir_trav: cannot open socket to ", port, "\n");
  195.     return (0);
  196.   }
  197.  
  198.   req = http_get(item:url, port:port);
  199.   send(socket:soc, data:req);
  200.   cod = recv_line(socket: soc, length: 80);
  201.   buf = http_recv(socket:soc, code: cod);
  202.   http_close_socket(soc);
  203.  
  204.   if (quickcheck)
  205.   {
  206.     if (" 200 " >< cod) return (1);
  207.     return (0);
  208.   }
  209.  
  210.   if ( ("ECHO" >< buf)          || ("SET " >< buf)             ||
  211.        ("export" >< buf)        || ("EXPORT" >< buf)           ||
  212.        ("mode" >< buf)          || ("MODE" >< buf)             || 
  213.        ("doskey" >< buf)        || ("DOSKEY" >< buf)           ||
  214.        ("[boot loader]" >< buf) || ("[fonts]" >< buf)          ||
  215.        ("[extensions]" >< buf)  || ("[mci extensions]" >< buf) ||
  216.        ("[files]" >< buf)       || ("[Mail]" >< buf)           ||
  217.        ("[operating systems]" >< buf)              )
  218.   {
  219.     return(1);
  220.   }
  221.   return(0);
  222. }
  223.  
  224. function check_win_dir_trav(port, url, quickcheck)
  225. {
  226.  if(do_check_win_dir_trav(port:port, url:url + rand(), quickcheck:quickcheck))
  227.     return NULL;
  228.  else
  229.     return do_check_win_dir_trav(port:port, url:url, quickcheck:quickcheck);
  230. }
  231.  
  232.  
  233. # This function does not return the headers!
  234. # So 'length' parameter does not include headers length, even if we 
  235. # have to read them. 
  236. # If Content-length is set, "length" only allows the function to read 
  237. # more data, if available. i.e., it is ignored most of the time.
  238. #
  239.  
  240. function http_recv_body(socket, headers, length)
  241. {
  242.   local_var    h, cl, l, min, max, x, n;
  243.   if (!headers)
  244.   {
  245.     h = http_recv_headers(socket);
  246.   }
  247.   else
  248.   {
  249.     h = headers;
  250.   }
  251.  
  252.   l = -1;
  253.   cl = egrep(pattern:"^Content-length: *[0-9]+", string: h, icase: 1);
  254.   if(cl)
  255.   {
  256.     l = int(ereg_replace(pattern: "Content-length: *([0-9]+).*", replace:"\1",
  257.         string: cl, icase: 1));
  258.   }
  259.   # "l" = Content-Length or -1 now
  260.  
  261.   max = -1;
  262.   min = -1;
  263.   
  264.  
  265.   if(l < 0 && egrep(pattern:"^transfer-encoding: chunked", string:h, icase:TRUE))
  266.   {
  267.    local_var tmp, body;
  268.    body = "";
  269.  
  270.    while(1)
  271.    {
  272.    tmp = recv_line(socket:socket, length:4096);
  273.    l = hex2dec(xvalue:tmp);
  274.    body  = strcat(body, recv(socket:socket, length:l+2, min:l+2));
  275.    if(l == 0){
  276.        return(body); # This is expected - don't put this line before the previous
  277.     }
  278.    }
  279.   }
  280.   
  281.   
  282.   if (length) max = length;
  283.   if (l >= 0) min = int(l);
  284.   if (l >= max || min >= max ) max = l;
  285.   if ( max < 0 )
  286.   {
  287.     #display("http_recv_body: bogus or no Content-length field, and no 'length' paramater set! Defaulting to 8 KB\n");
  288.     max = 8192;
  289.   }
  290.   #display("http_recv_body: min=", min, "; max=", max, "\n");
  291.   if (min > 0)
  292.   {
  293.     x = recv(socket: socket, length: max, min: min);
  294.   }
  295.   else
  296.   {
  297.     n = recv(socket: socket, min:max, length: max);
  298.     x = n;
  299.     while ( strlen(n) >= max && max != 0 )
  300.     {
  301.      n = recv(socket: socket, length: max);
  302.      x += n;
  303.      if( strlen(x) > 1048576){
  304.         display("http_recv_body: read stopped after 1 MB!\n");
  305.     break;
  306.     }
  307.     }
  308.   }
  309.  
  310.   return(x);
  311. }
  312.  
  313. # This function reads everything
  314. # Note that bodylength will be ignored if the Content-length field is set
  315.  
  316. function http_recv(socket, code)
  317. {
  318.   local_var    h, b, l;
  319.   if (code)
  320.   {
  321.     h = strcat(code);    # Convert to string, just in case
  322.     repeat
  323.     {
  324.       l = recv_line(socket: socket, length: 2048);
  325.       h = h + l;
  326.     }
  327.     until (! l || l =~ '^[\r\n]+$'); # EOF or empty line
  328.     if (!l) return h;
  329.   }
  330.   else
  331.   {
  332.     h = http_recv_headers(socket);
  333.     if(!h) return(NULL);
  334.     h = strcat(h, '\r\n');
  335.   }
  336.   b = http_recv_body(socket: socket, headers: h, length:0);
  337.   return strcat(h, b);
  338. }
  339.  
  340. function http_recv_length(socket, bodylength)
  341. {
  342.   local_var    h, b;
  343.   h = http_recv_headers(socket);
  344.   b = http_recv_body(socket: socket, headers: h, length: bodylength);
  345.   return strcat(h, '\r\n', b);
  346. }
  347.  
  348. function http_send_recv(port, data)
  349. {
  350.   local_var    s, r;
  351.  
  352.   s = http_open_socket(port);
  353.   if (! s) return;
  354.   send(socket: s, data: data);
  355.   r = http_recv(socket: s);
  356.   http_close_socket(s);
  357.   return r;
  358. }
  359.  
  360.  
  361. function cgi_dirs()
  362. {
  363.  local_var kb;
  364.  kb = get_kb_list("/tmp/cgibin");
  365.  if(isnull(kb))kb = make_list("/cgi-bin", "/scripts", "");
  366.  else kb = make_list(kb, "");
  367.  
  368.  return(kb); 
  369. }
  370.  
  371.  
  372.  
  373.  
  374. function can_host_php(port)
  375. {
  376.  local_var banner, sig, files;
  377.  
  378.  banner = get_http_banner(port:port);
  379.  if ( ! banner ) return 0;
  380.  else 
  381.  {
  382.   if ( egrep(pattern:"^Server:.*IceWarp", string:banner, icase:1 ) )
  383.     return 1;
  384.  
  385.  if ( egrep(pattern:"^Server:.*apache|thttpd|aolserver|pi3web|zeus|iis", string:banner, icase:1 ) )
  386.         {
  387.         #display(get_host_ip(), " may host PHP\n");
  388.         return 1;
  389.         }
  390.  }
  391.  
  392.  files = get_kb_list("www/" + port + "/content/extensions/php*");
  393.  if ( !isnull(files) ) {
  394.         #display(get_host_ip(), " hosts PHP - ", files[0], "\n");
  395.         return 1; # Hosting .php+ files
  396.          }    
  397.  
  398.  
  399.  sig = get_kb_item("www/hmap/" + port + "/description");
  400.  if ( ! sig ) { 
  401.     #display(get_host_ip(), " has no sig\n"); 
  402.       # If it has a banner but did not match above, then declare this is not a PHP
  403.     # web site (dangerous, so disabled)
  404.     #if ( egrep(pattern:"^Server:.*", string:banner) ) return 0;
  405.     #else 
  406.      return 1; # Unknown web server - might be able to host a PHP website
  407.     }
  408.  
  409.  if ( egrep(pattern:"apache|thttpd|aolserver|pi3web|zeus|iis", string:sig, icase:1 ) )
  410.     {
  411.     #display(get_host_ip(), " may be PHP site (sig)\n");
  412.     return 1;
  413.     }
  414.  else {
  415.     #display(get_host_ip(), " is definitely NOT a PHP site (sig) - ", sig, "\n");
  416.     return 0;
  417.     }
  418. }
  419.  
  420. function can_host_asp(port)
  421. {
  422.  local_var banner, sig, files;
  423.  
  424.  banner = get_http_banner(port:port);
  425.  if ( ! banner ) return 0;
  426.  else 
  427.  {
  428.  if ( egrep(pattern:"^Server:.*IIS", string:banner, icase:1 ) )
  429.         {
  430.         #display(get_host_ip(), " may host ASP\n");
  431.         return 1;
  432.         }
  433.  }
  434.  
  435.  files = get_kb_list("www/" + port + "/content/extensions/asp");
  436.  if ( !isnull(files) ) {
  437.         #display(get_host_ip(), " hosts ASP - ", files[0], "\n");
  438.         return 1; # Hosting .asp files
  439.          }    
  440.  
  441.  
  442.  sig = get_kb_item("www/hmap/" + port + "/description");
  443.  if ( ! sig ) { 
  444.     #display(get_host_ip(), " has no sig\n"); 
  445.       # Could not fingerprint it, even though we know that IIS fingerprint
  446.         # is quite reliable 
  447.     if ( egrep(pattern:"^Server:.*", string:banner) ) return 0;
  448.     else 
  449.      return 1; # Unknown web server - might be able to host a ASP website
  450.     }
  451.  
  452.  if ( egrep(pattern:"iis", string:sig, icase:1 ) )
  453.     {
  454.     #display(get_host_ip(), " may be ASP site (sig)\n");
  455.     return 1;
  456.     }
  457.  else {
  458.     #display(get_host_ip(), " is definitely NOT a ASP site (sig) - ", sig, "\n");
  459.     return 0;
  460.     }
  461. }
  462.  
  463. function http_40x(port, code)
  464. {
  465.   local_var    no404;
  466.  
  467.   if (ereg(string: code, pattern: "^HTTP/1\.[01] +40[0-9]"))
  468.    return TRUE;
  469.  
  470.   no404 = get_kb_item("www/no404/"+port);
  471.   if (no404 && no404 >< code)
  472.     return TRUE;
  473.   return FALSE;
  474. }
  475.